﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using PaperPluginUtilities;

namespace TwikiLinkScanners
{
    public static class TwikiParseHelpers
    {
        private static string[] MainTwikiWords = {
                                      "WebHome",
                                      "AtalsResults",
                                      "WebHome",
                                      "AtlasResults",
                                      "AtlasDetectors",
                                      "AtlasTrigger",
                                      "AtlasComputing",
                                      "DataPreparation",
                                      "AtlasHelp",
                                      "AtlasGlossary",
                                      "AtlasResults",
                                      "StandardModelPublicResults",
                                      "TopPublicResults",
                                      "ExoticsPublicResults",
                                      "HiggsPublicResults",
                                      "SusyPublicResults",
                                      "HeavyIonsPublicResults",
                                      "BPhysPublicResults",
                                      "TwikiAccess",
                                      "DocumentationManagementPublicTWikiAccess"
                                                 };

        /// <summary>
        /// Return true if this twiki word matches any of the main twiki word - which we don't
        /// want to follow.
        /// </summary>
        /// <param name="twikiWord"></param>
        /// <returns></returns>
        internal static bool MainATLASTwikiWord(string twikiWord)
        {
            if (MainTwikiWords.Contains(twikiWord))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Make sure we are being redirected to a single twiki word.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        internal static bool IsSingleTwikiWord(string twikiWord)
        {
            if (twikiWord.Length < 2)
            {
                return false;
            }
            var nonLetter = from c in twikiWord where !char.IsLetterOrDigit(c) select c;
            if (nonLetter.Any())
            {
                return false;
            }
            return true;
        }

        const string ATALSTwikiStartPrefix = "https://twiki.cern.ch/twiki/bin/view/Atlas";
        internal static bool isATLASTwikiLink(Uri u)
        {
            return u.OriginalString.StartsWith(ATALSTwikiStartPrefix);
        }

        /// <summary>
        /// Extracts the twiki word out of a uri. It assumes that what we are looking at is just a good
        /// twiki word and nothing more complex!
        /// </summary>
        /// <param name="u"></param>
        /// <returns></returns>
        internal static string ExtractATLASTwikiWord(Uri u)
        {
            return u.OriginalString.Substring(ATALSTwikiStartPrefix.Length + 1);
        }

        /// <summary>
        /// Given the HTML, see if this page is actually a good page for us to be
        /// scannign for public plots (not all ATLAS pages are public that should be).
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        internal static bool isATLASPublicResultsPage(HtmlNode document)
        {
            return isPublicSetOfTwikiBreadcrumbTrail(ExtractATLASTwikiBreadCrumbs(document));
        }

        /// <summary>
        /// Returns true if the twiki bread crumbs that are given here are "good" for a public page.
        /// </summary>
        /// <param name="crumbs"></param>
        /// <returns></returns>
        public static bool isPublicSetOfTwikiBreadcrumbTrail(IEnumerable<string> crumbs)
        {
            if (crumbs.Any(s => (s == "AtlasResults") || (s == "ApprovedDetectorPlots") || (s == "InDetTrackingPerformanceCSCFigures") || (s == "TriggerCSCNotes") || (s == "AtlasReultsEcmDependence")))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// Given a twiki page, extract the atlas twiki bread crumb trail you see across the top. THis
        /// is what usually puts things in the hierarchy. Public to make it testable...
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public static IEnumerable<string> ExtractATLASTwikiBreadCrumbs(HtmlNode document)
        {
            var allSpans = new EnumerableWrapper<HtmlNode>(document.SelectNodes("//span[@class]"));
            var breadSpan = from s in allSpans
                            let c = s.Attributes["class"].Value
                            where c == "patternHomePath twikiLeft"
                            select s;
            var trail = breadSpan.FirstOrDefault();
            if (trail == null)
            {
                return Enumerable.Empty<string>();
            }

            ///
            /// The text of the links is what contains what we want...
            /// 

            var linkNames = trail.ScanSubNodes("a");
            var text = from l in linkNames
                       select l.InnerText;

            return text;

        }
    }
}
